package it.unibo.util.timer.test.unit;

import static org.junit.Assert.*;

import java.util.Date;

import it.unibo.util.timer.Timer;
import it.unibo.util.timer.TimerEvent;
import it.unibo.util.timer.TimerEventListener;

import org.junit.Test;

public class TimerTestCase 
{
	static int limit = 2000;
	static int delta = 10;
	static boolean ok = false;


	@Test(expected=IllegalArgumentException.class)
	public void testCreation()
	{
		new Timer(-5);
	}

	@Test
	public void testFire()
	{	
		Timer timer = new Timer(limit);

		Date now = new Date();
		final long startTime = now.getTime();
		timer.startTimer();
		timer.addTimerListener(new TimerEventListener() {

			@Override
			public void onTimerFired(TimerEvent event) 
			{
				long firedTime = System.currentTimeMillis();
				if((firedTime - startTime) >= limit - delta && (firedTime - startTime) <= limit + delta)
					ok = true;

			}
		});


		assertTrue(timer.isRunning());

		try 
		{
			Thread.sleep(limit + 500);			// Altrimenti JUnit termina e dice "ok"
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		assertTrue(ok);
		assertFalse(timer.isRunning());
	}

	@Test
	public void testStopTimer()
	{
		Timer timer = new Timer(limit);
		timer.startTimer();
		assertTrue(timer.isRunning());

		timer.stopTimer();
		assertFalse(timer.isRunning());
	}

	@Test
	public void testResetTimer()
	{
		final int newLimit = 5000;
		final int timeBeforeReset = 2000;
		Timer timer = new Timer(newLimit);

		Date now = new Date();
		final long startTime = now.getTime();
		timer.startTimer();
		timer.addTimerListener(new TimerEventListener() {

			@Override
			public void onTimerFired(TimerEvent event) 
			{
				long firedTime = System.currentTimeMillis();
				// Controllo che il tempo passato tra il primo avvio e il fire sia di 7 secondi
				if((firedTime - startTime) >= newLimit + timeBeforeReset - delta && 
						(firedTime - startTime) <= newLimit + timeBeforeReset + delta)
					ok = true;

			}
		});

		assertTrue(timer.isRunning());
		
		try 
		{
			Thread.sleep(timeBeforeReset);			// Dormo per due secondi e poi resetto il timer
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		timer.resetTimer();

		try 
		{
			Thread.sleep(newLimit + timeBeforeReset + 500);		// Altrimenti JUnit termina e dice "ok"
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		assertTrue(ok);
		assertFalse(timer.isRunning());
	}
}
